package net.lanelife.casino.caipiao.service;

import java.util.List;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;

import net.lanelife.casino.caipiao.entity.Job;
import net.lanelife.casino.caipiao.job.handler.RechargeJobHandler;
import net.lanelife.casino.caipiao.job.handler.WithdrawApplyJobHandler;
import net.lanelife.casino.caipiao.repository.api.IJobRepository;
import net.lanelife.casino.caipiao.service.api.IJobService;
import net.lanelife.casino.common.repository.support.GenericRepository;
import net.lanelife.casino.common.service.support.GenericService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class JobService extends GenericService<Job, Integer> implements IJobService {

	@PersistenceContext
	private EntityManager em;
	
	@Autowired
	private IJobRepository repository;
	
	@Autowired
	private RechargeJobHandler rechargeJobHandler;
	
	@Autowired
	private WithdrawApplyJobHandler withdrawApplyJobHandler;
	
	public JobService() {
		super(Job.class);
	}
	
	@Override
	protected GenericRepository<Job, Integer> getRepository() {
		return repository;
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(rollbackFor = Exception.class)
	public List<Job> selectJobs(int limit) {
		String uuid = UUID.randomUUID().toString().toUpperCase();
		int n = em.createNativeQuery("update TB_JOB set UUID=:uuid where UUID is null limit :limit").setParameter("uuid", uuid).setParameter("limit", limit).executeUpdate();
		if (n > 0) {
			return em.createQuery("FROM Job WHERE uuid=:uuid").setParameter("uuid", uuid).getResultList();
		}
		return null;
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public void executeJob(Job job) {
		try {
			// 锁定该任务
			job = repository.findOne(job.getId(), LockModeType.PESSIMISTIC_WRITE);
			
			switch (job.getType()) {
			case RECHARGE:	// 充值任务
				rechargeJobHandler.handle(job);
				break;
			case WITHDRAW_APPLY: //提款申请任务
				withdrawApplyJobHandler.handle(job);
				break;
			default:
				throw new RuntimeException("unknow job type.");
			}
			
			// 删除该任务
			repository.delete(job);
			
		} catch (Throwable e) {
			// 处理失败任务
			e.printStackTrace();
		}
	}

}
